package com.seu.vcampus.dao;

import com.seu.vcampus.vo.Order;
import java.sql.*;
import java.util.List;
import java.util.ArrayList;

/**
 * 订单数据访问类
 * 负责订单数据的CRUD操作
 * 
 * @author 虚拟校园开发团队
 * @since 1.0.0
 */
public class OrderDao {
private Connection connection;
	
	private static final String selectOrderByOID = "SELECT * FROM Order WHERE oID = ?";
	private static final String selectOrderByUser = "SELECT * FROM Order WHERE user = ?";
	private static final String selectAllOrder = "SELECT * FROM Order";
	private static final String insertOrder = "INSERT INTO Order (oID, user, product, time, quantity, price) VALUES (?, ?, ?, ?, ?, ?)";
	private static final String deleteOrder = "DELETE FROM Order WHERE oID = ?";
	private static final String deleteAllUserOrder = "DELETE FROM Order WHERE user = ?";
	private static final String updateOrder = "UPDATE Order set user = ?, product = ?, time = ?, quantity = ?, price = ? WHERE oID = ?";
	private static final String countUserOrder = "SELECT COUNT(*) FROM Order WHERE user =  ?";
	public OrderDao(Connection connection)
	{
		this.connection = connection;
		initializeTable();
	}
	
	/**
	 * 初始化订单表
	 */
	private void initializeTable()
	{
		try(Statement stmt = connection.createStatement())
		{
			String createOrderTable = "CREATE TABLE IF NOT EXISTS Orders("
					+ "oID VARCHAR(50) PRIMARY KEY, "
					+ "user VARCHAR(50) NOT NULL, "
					+ "product VARCHAR(50) NOT NULL, "
					+ "time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
					+ "quantity INTEGER NOT NULL, "
					+ "price DOUBLE NOT NULL"
					+ ")";
			stmt.execute(createOrderTable);
		}
		catch(SQLException e)
		{
			throw new RuntimeException("Failed to create order table", e);
		}
	}
	
	/**
	 * 保存订单
	 * @param o 订单对象
	 * @return 是否保存成功
	 */
	public boolean save(Order o)
	{
		Order existingOrder = findById(o.getID());
		
		if(existingOrder == null)
		{
			try(PreparedStatement stmt = connection.prepareStatement(insertOrder))
			{
				stmt.setString(1, o.getID());
				stmt.setString(2, o.getUser());
				stmt.setString(3, o.getProduct());
				stmt.setTimestamp(4, o.getTime());
				stmt.setInt(5, o.getQuantity());
				stmt.setDouble(6, o.getPrice());
				return stmt.executeUpdate() > 0;
			}
			catch(SQLException e)
			{
				throw new RuntimeException("Failed to save order", e);
			}
		}
		else
		{
			try(PreparedStatement stmt = connection.prepareStatement(updateOrder))
			{
				stmt.setString(1, o.getID());
				stmt.setString(2, o.getUser());
				stmt.setString(3, o.getProduct());
				stmt.setTimestamp(4, o.getTime());
				stmt.setInt(5, o.getQuantity());
				stmt.setDouble(6, o.getPrice());
				return stmt.executeUpdate() > 0;
			}
			catch(SQLException e)
			{
				throw new RuntimeException("Failed to save order", e);
			}
		}
	}
	
	/**
	 * 根据订单号查找订单
	 * @param oid 订单号
	 * @return 订单对象，不存在返回null
	 */
	public Order findById(String oid)
	{
		try(PreparedStatement stmt = connection.prepareStatement(selectOrderByOID))
		{
			stmt.setString(1, oid);
			ResultSet rs = stmt.executeQuery();
			
			if(rs.next())
			{
				return mapResultSetToOrder(rs);
			}
			return null;
		}
		catch(SQLException e)
		{
			throw new RuntimeException("Failed to find order by ID", e);
		}
	}
	
	/**
	 * 根据用户ID查找订单
	 * @param uid 用户ID
	 * @return 订单对象列表
	 */
	public List<Order> findByUser(String uid)
	{
		try(PreparedStatement stmt = connection.prepareStatement(selectOrderByUser))
		{
			stmt.setString(1, uid);
			ResultSet rs = stmt.executeQuery();
			
			List<Order> ret = new ArrayList<>();
			while(rs.next())
			{
				ret.add(mapResultSetToOrder(rs));
			}
			return ret;
		}
		catch(SQLException e)
		{
			throw new RuntimeException("Failed to find order by ID", e);
		}
	}
	
	/**
	 * 获取所有订单
	 * @return 订单对象列表
	 */
	public List<Order> findAll()
	{
		try(PreparedStatement stmt = connection.prepareStatement(selectAllOrder))
		{
			List<Order> ret = new ArrayList<>();
			ResultSet rs = stmt.executeQuery();
			
			while(rs.next())
			{
				ret.add(mapResultSetToOrder(rs));
			}
			return ret;
		}
		catch(SQLException e)
		{
			throw new RuntimeException("Failed to find all orders", e);
		}
	}
	
	/**
	 * 根据订单号删除订单
	 * @param oid 订单号
	 * @return 是否删除成功
	 */
	public boolean delete(String oid)
	{
		try(PreparedStatement stmt = connection.prepareStatement(deleteOrder))
		{
			stmt.setString(1, oid);
			return stmt.executeUpdate() > 0;
		}
		catch(SQLException e)
		{
			throw new RuntimeException("Failed to delete order", e);
		}
	}
	
	/**
	 * 根据用户ID删除用户所有订单
	 * @param uid 用户ID
	 * @return 是否删除成功
	 */
	public boolean deleteUserAll(String uid)
	{
		try(PreparedStatement stmt = connection.prepareStatement(deleteAllUserOrder))
		{
			stmt.setString(1, uid);
			return stmt.executeUpdate() > 0;
		}
		catch(SQLException e)
		{
			throw new RuntimeException("Failed to delete user all order", e);
		}
	}
	
	/**
	 * 获取用户订单数量
	 * @param uid 用户ID
	 * @return 用户订单数量
	 */
	public int getUserOrderCount(String uid)
	{
		try(PreparedStatement stmt = connection.prepareStatement(countUserOrder))
			{
				stmt.setString(1, uid);
				ResultSet rs = stmt.executeQuery();
				return rs.next() ? rs.getInt(1) : 0;
			}
			catch(SQLException e)
			{
				throw new RuntimeException("Failed to get user CartItem count", e);
			}
	}
	
	/**
	 * 将ResultSet对象映射为Order
	 * @param rs ResultSet对象
	 * @return 订单对象
	 */
	public Order mapResultSetToOrder(ResultSet rs) throws SQLException
	{
		return new Order(rs.getString("oID"), rs.getString("user"), rs.getString("product"), rs.getTimestamp("time"), rs.getInt("quantity"), rs.getDouble("price"));
	}
}
